package org.jeecg.modules.demo.workflow.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.modules.demo.bean.entity.WflowFormData;
import org.jeecg.modules.demo.mapper.WflowFormDataMapper;
import org.jeecg.modules.demo.utils.R;
import org.jeecg.modules.demo.utils.UserUtil;
import org.jeecg.modules.demo.workflow.bean.vo.ProcessInstanceVo;
import org.jeecg.modules.demo.workflow.bean.vo.ProcessStartParamsVo;
import org.jeecg.modules.demo.workflow.service.ProcessInstanceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author : willian fu
 * @date : 2022/8/24
 */
@RestController
@RequestMapping("wflow/process")
@Slf4j
public class ProcessInstanceController {

    @Autowired
    private ProcessInstanceService processService;

    @Autowired
    private WflowFormDataMapper wflowFormDataMapper;

    /**
     * 查询工作台上方 我发起的、带我处理、关于我的统计数量
     *
     * @return 统计数据
     */
    @GetMapping("instance/count")
    public Object getProcessInstanceCount() {
        return R.ok(processService.getProcessInstanceCount());
    }

    /**
     * 发起审批流程
     *
     * @param defId  流程定义ID
     * @param params 参数
     * @return 操作结果
     */
    @PostMapping("start/{defId}")
    public Object startTheProcess(@PathVariable String defId,
                                  @RequestBody ProcessStartParamsVo params) {
        String instanceId = processService.startProcess(defId, params);
        return R.ok("启动流程实例 " + instanceId + " 成功");
    }

    /**
     * 根据instanceid查询对应wflowfromdata的字段信息
     *
     * @return 统计数据
     */
    @AutoLog(value = "根据instanceid查询对应wflowfromdata的字段信息")
    @Operation(summary = "根据instanceid查询对应wflowfromdata的字段信息", description = "根据instanceid查询对应wflowfromdata的字段信息")
    @GetMapping("instance/wflowfromdata")
    public Object getProcessInstanceWflowfromdata(String instanceId) {
        List<WflowFormData> wflowFormData = wflowFormDataMapper.selectList(new LambdaQueryWrapper<WflowFormData>().eq(WflowFormData::getInstanceId, instanceId));
        Map<String, String> map = new HashMap<>();
        wflowFormData.forEach(w -> map.put(w.getFieldName(), w.getFieldValue()));
        return R.ok(map);
    }

    /**
     * 获取审批流程实例待处理的任务列表
     *
     * @param instanceId 流程实例ID
     * @return 列表数据
     */
    @GetMapping("{instanceId}/taskList")
    public Object getProcessInstanceTaskList(@PathVariable String instanceId) {
        return R.ok(processService.getProcessInstanceTaskList(instanceId));
    }

    /**
     * 获取系统内发起的流程
     *
     * @param pageSize 每页数量
     * @param pageNo   页码
     * @param code     表单流程ID（流程定义KEY）
     * @param finished 流程是否已经结束
     * @return 列表数据
     */
    @GetMapping("mySubmitted")
    public Object getUserSubmittedList(@RequestParam(defaultValue = "20") Integer pageSize,
                                       @RequestParam(defaultValue = "1") Integer pageNo,
                                       @RequestParam(required = false) String code,
                                       @RequestParam(required = false) String[] startTimes,
                                       @RequestParam(required = false) String keyword,
                                       @RequestParam(required = false) Boolean finished,
                                       @RequestParam(required = false) String fieldId,
                                       @RequestParam(required = false) String fieldVal) {
        return R.ok(processService.getUserSubmittedList(pageSize, pageNo, UserUtil.getLoginUserId(), code,
                finished, startTimes, keyword, fieldId, fieldVal));
    }

    @Operation(summary = "删除全部流程实例", description = "删除全部流程实例")
    @DeleteMapping("deletewflow")
    public void getUserSubmittedList1(@RequestParam(defaultValue = "20") Integer pageSize,
                                      @RequestParam(defaultValue = "1") Integer pageNo,
                                      @RequestParam(required = false) String code,
                                      @RequestParam(required = false) String[] startTimes,
                                      @RequestParam(required = false) String keyword,
                                      @RequestParam(required = false) Boolean finished,
                                      @RequestParam(required = false) String fieldId,
                                      @RequestParam(required = false) String fieldVal) {
        Page<ProcessInstanceVo> page =  processService.getUserSubmittedList(pageSize, pageNo, UserUtil.getLoginUserId(), code,
                finished, startTimes, keyword, fieldId, fieldVal);
        List<String> instanceIds = page.getRecords().stream().map(ProcessInstanceVo::getInstanceId).collect(Collectors.toList());
        System.out.println("instanceIds = " + instanceIds);
        delProcessInstance1(instanceIds);
    }

    /**
     * 获取系统中所有已发起的流程实例
     *
     * @param pageSize 每页数量
     * @param pageNo   页码
     * @param code     表单流程ID（流程定义KEY）
     * @param finished 流程是否已经结束
     * @return 列表数据
     */

    @GetMapping("submittedList")
    public Object getSubmittedList(@RequestParam(defaultValue = "20") Integer pageSize,
                                   @RequestParam(defaultValue = "1") Integer pageNo,
                                   @RequestParam(required = false) String code,
                                   @RequestParam(required = false) String[] startTimes,
                                   @RequestParam(required = false) String keyword,
                                   @RequestParam(required = false) Boolean finished,
                                   @RequestParam(required = false) String fieldId,
                                   @RequestParam(required = false) String fieldVal) {
        return R.ok(processService.getUserSubmittedList(pageSize, pageNo, null, code,
                finished, startTimes, keyword, fieldId, fieldVal));
    }

    /**
     * 查询流程表单数据及审批的进度步骤
     *
     * @param instanceId 流程实例ID
     * @param nodeId     当前获取流程人员关联的流程节点ID
     * @return 流程进度及表单详情
     */
    @GetMapping("progress/{instanceId}/{nodeId}")
    public Object getProcessFormAndInstanceProgress(@PathVariable String instanceId,
                                                    @PathVariable(required = false) String nodeId) {
//        System.out.println(" 1111 " );
        return R.ok(processService.getInstanceProgress(nodeId, instanceId));
    }

    /**
     * 获取抄送我的事项
     *
     * @param pageSize 每页数量
     * @param pageNo   页码
     * @param code     表单模型ID，流程定义KEY
     * @return 超送我的审批实例
     */
    @GetMapping("ccMe")
    public Object getCcMeInstance(@RequestParam(defaultValue = "20") Integer pageSize,
                                  @RequestParam(defaultValue = "1") Integer pageNo,
                                  @RequestParam(required = false) String[] startTimes,
                                  @RequestParam(required = false) String code) {
        return R.ok(processService.getCcMeInstance(pageSize, pageNo, code, startTimes));
    }

    /**
     * 删除流程实例
     *
     * @param instanceId 实例ID
     * @return 操作结果
     */
//    @ApiOperation(value="删除流程实例", notes="删除流程实例")
    @DeleteMapping("instance/{instanceId}")
    public Object delProcessInstance(@PathVariable String instanceId) {
        processService.delProcessInstance(instanceId);
        return R.ok("删除流程实例成功");
    }


    @Operation(summary = "删除流程实例", description = "删除流程实例")
    @DeleteMapping("/instance1")
    public Object delProcessInstance1(@RequestParam(name = "instanceIds") List<String> instanceIds) {
        // 使用多线程删除流程实例
        if (instanceIds != null && !instanceIds.isEmpty()) {
            // 创建线程池，核心线程数根据实际情况调整
            ExecutorService executor = Executors.newFixedThreadPool(10);

            for (String instantId : instanceIds) {
                executor.submit(() -> {
                    try {
                        // 执行流程实例删除
                        processService.delProcessInstance(instantId);
                    } catch (Exception e) {
                        System.err.println("删除流程实例失败，ID: " + instantId + ", 错误: " + e.getMessage());
                        // 可以根据需要进行重试或其他处理
                    }
                });
            }

            // 关闭线程池
            executor.shutdown();
            try {
                // 等待所有任务完成
                if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                    // 超时后强制关闭
                    executor.shutdownNow();
                }
            } catch (InterruptedException e) {
                executor.shutdownNow();
            }
        }
        return R.ok("删除流程实例成功");
    }



}


